#引言 之前跟着教程用Django写过一个博客,不过都是看着抄,能运行就下一章,没学到啥。现在决定重新用flask写个,然后每次看完都记录学到什么,慢可以,但不能写出了个博客问你啥你都不知道
#官方文档的入门指南 ##Step 0:创建文件 教你怎么创建文件,我直接用pycharm自动生成了就直接跳过 ##Step 1:数据库架构 创建个数据库
drop table if exists entries;create table entries ( id integer primary key autoincrement, title text not null, 'text' text not null);复制代码
其他都懂,为啥text
要有单引号? ##Step 2:应用程序设置代码
app = Flask(__name__) # create the application instance :)app.config.from_object(__name__) # load config from this file , flaskr.py# Load default config and override config from an environment variableapp.config.update(dict( DATABASE=os.path.join(app.root_path, 'flaskr.db'), SECRET_KEY='development key', USERNAME='admin', PASSWORD='default'))app.config.from_envvar('FLASKR_SETTINGS', silent=True)复制代码
整个设置程序,指南里说最好的办法是把这些配置信息一起写到一个.ini
或者.py
的文件里 Flask()
是创建一个应用程序 app.config.from_object
设置从哪里加载配置文件 app.config.update
是设置配置信息,Flask会找到配置信息里面大写的参数进行初始化,其中
app.root_path
和os.path
是为了适应不同的操作系统的文件系统secret_key
是用来保护用户端的session安全的
app.config.from_envvar
是表示用环境变量来设置需要加载的配置文件,因为开发中和上线时需要的配置文件是不一样的(像是DEBUG
)所以可以通过在shell脚本中设置要配置的文件,在运行Flask,后面的silent
的意思是如果没有给环境变量赋值不报错 ##Step 3:像安装包一样的安装flaskr 里面讲了为了以后可以用pip install ***
的方式来安装程序,所以参照python打包指南里的方式来设计程序目录。
/flaskr /flaskr __init__.py /static /templates flaskr.py schema.sql setup.py MANIFEST.in复制代码
里面新增了setup.py
,__init__.py
,MANIFEST.in
setup.py
from setuptools import setupsetup( name='flaskr', packages=['flaskr'], include_package_data=True, install_requires=[ 'flask', ],)复制代码
MANIFEST.in 指定那些文件需要被包含
graft flaskr/templatesgraft flaskr/staticinclude flaskr/schema.sql复制代码
文档里说明的命令代表的内容
命令 | 内容 |
---|---|
include pat1 pat2 ... | include all files matching any of the listed patterns |
exclude pat1 pat2 ... | exclude all files matching any of the listed patterns |
recursive-include dir pat1 pat2 ... | include all files under dir matching any of the listed patterns |
recursive-exclude dir pat1 pat2 ... | exclude all files under dir matching any of the listed patterns |
global-include pat1 pat2 ... | include all files anywhere in the source tree matching — & any of the listed patterns |
global-exclude pat1 pat2 ... | exclude all files anywhere in the source tree matching — & any of the listed patterns |
prune dir | exclude all files under dir |
graft dir | include all files under dir |
init.py
from .flaskr import app复制代码
运行方式
export FLASK_APP=flaskrexport FLASK_DEBUG=trueflask run复制代码
windows下用set
来代替export
##Step 4:数据库连接 里面提到了俩个上下文(context),一个application上下文和一个request上下文,我感觉context翻译成语境好点,上下文看的一脸懵逼,对应这俩上下文有俩个关键字request
,g
来分别代表request和application 然后是创建数据库连接的代码
def get_db(): """Opens a new database connection if there is none yet for the current application context. """ if not hasattr(g, 'sqlite_db'): g.sqlite_db = connect_db() return g.sqlite_db复制代码
关闭连接
@app.teardown_appcontextdef close_db(error): """Closes the database again at the end of the request.""" if hasattr(g, 'sqlite_db'): g.sqlite_db.close()复制代码
teardown_appcontext()
会在每次application 上下文摧毁时调用 application上下文是先于request上下文创建时创建,后于request上下文结束时结束 ##Step 5:创建数据库 通过在flask命令行里加入一个钩子方法用来初始化数据库
def init_db(): db = get_db() with app.open_resource('schema.sql', mode='r') as f: db.cursor().executescript(f.read()) db.commit()@app.cli.command('initdb')def initdb_command(): """Initializes the database.""" init_db() print('Initialized the database.')复制代码
app.cli.command()
装饰器会在flask命令行里注册一个新的initdb
命令,当执行这个命令后flask会自动创建一个application上下文,当执行完方法里的代码后再自己摧毁和释放数据库连接 open_resource()
是一个方便开发者的方法,可以直接定位项目中的资源文件夹位置 现在开始执行初始化
set FLASK_APP=flaskr //这里文档里没写所以运行时会提示没有该命令flask initdbInitialized the database.复制代码
##Step 6:视图方法 主页视图
@app.route('/')def show_entries(): db = get_db() cur = db.execute('select title, text from entries order by id desc') entries = cur.fetchall() return render_template('show_entries.html', entries=entries)复制代码
添加新实体
@app.route('/add', methods=['POST'])def add_entry(): if not session.get('logged_in'): abort(401) db = get_db() db.execute('insert into entries (title, text) values (?, ?)', [request.form['title'], request.form['text']]) db.commit() flash('New entry was successfully posted') return redirect(url_for('show_entries'))复制代码
abort()
发送错误代码给WSGI应用
flask.flash(message, category=’message’) Flashes a message to the next request. In order to remove the flashed message from the session and to display it to the user, the template has to call
不太懂,说是闪烁消息,感觉想Android里面的toast,但是感觉又是Android里面的广播 例子的实现方式是想日志一样,就是为了友好的人机交互 文档里写会发送信息到下个请求和重定向到show_entries
网页上 登陆
@app.route('/login', methods=['GET', 'POST'])def login(): error = None if request.method == 'POST': if request.form['username'] != app.config['USERNAME']: error = 'Invalid username' elif request.form['password'] != app.config['PASSWORD']: error = 'Invalid password' else: session['logged_in'] = True flash('You were logged in') return redirect(url_for('show_entries')) return render_template('login.html', error=error)复制代码
登出
@app.route('/logout')def logout(): session.pop('logged_in', None) flash('You were logged out') return redirect(url_for('show_entries'))复制代码
##Step 7:模板
layout.html
Flaskr 复制代码Flaskr
{% for message in get_flashed_messages() %}{ { message }}{% endfor %} {% block body %}{% endblock %}
show_entries.html
{% extends "layout.html" %}{% block body %} {% if session.logged_in %}{% endif %}
- {% for entry in entries %}
{ { entry.title }}
{ { entry.text|safe }} {% else %}- Unbelievable. No entries here so far {% endfor %}
login.html
{% extends "layout.html" %}{% block body %}{% endblock %}复制代码Login
{% if error %}Error: {
{ error }}{% endif %}
style.css
body { font-family: sans-serif; background: #eee; }a, h1, h2 { color: #377ba8; }h1, h2 { font-family: 'Georgia', serif; margin: 0; }h1 { border-bottom: 2px solid #eee; }h2 { font-size: 1.2em; }.page { margin: 2em auto; width: 35em; border: 5px solid #ccc; padding: 0.8em; background: white; }.entries { list-style: none; margin: 0; padding: 0; }.entries li { margin: 0.8em 1.2em; }.entries li h2 { margin-left: -1em; }.add-entry { font-size: 0.9em; border-bottom: 1px solid #ccc; }.add-entry dl { font-weight: bold; }.metanav { text-align: right; font-size: 0.8em; padding: 0.3em; margin-bottom: 1em; background: #fafafa; }.flash { background: #cee5F5; padding: 0.5em; border: 1px solid #aacbe2; }.error { background: #f0d6d6; padding: 0.5em; }复制代码
#在这停顿 大概了解到了整个flask的基本运行方法